package cn.wizzer.app.crown.modules.services.impl.result;

import cn.wizzer.app.crown.modules.models.CrownMatch;
import cn.wizzer.app.crown.modules.models.constant.CrownConstant;
import cn.wizzer.app.crown.modules.services.CrownMatchService;
import cn.wizzer.app.crown.modules.services.result.MatchResultService;
import cn.wizzer.app.sys.modules.services.SysParamService;
import cn.wizzer.framework.util.DateUtil;
import cn.wizzer.framework.util.Result;
import cn.wizzer.framework.base.service.BaseServiceImpl;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSONArray;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.Times;
import org.nutz.log.Log;
import org.nutz.log.Logs;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;


@IocBean(args = {"refer:dao"})
@Service(interfaceClass = MatchResultService.class)
public class MatchResultServiceImpl extends BaseServiceImpl<CrownMatch> implements MatchResultService {

    public MatchResultServiceImpl(Dao dao) {
        super(dao);
    }

    private static final Log log = Logs.get();

    @Inject
    private RedisService redisService;
    @Inject
    private CrownMatchService matchService;
    @Inject
    @Reference
    private SysParamService sysParamService;

    private static final Pattern MATCH_COMPILE = Pattern.compile("gdata = Array\\((.*?)\\);");


    /**
     * key: 赛事异常信息
     * value: 赛事阶段标记 & 文字
     */
    private Map<Integer, String> tagMap = Result.createHashMap(
            74, "NO4",
            68, "NO8"
    );


    /**
     * 进球数爬取
     *
     * @param jsonArray 爬取的数据源
     * @param mid       CrownMatch对象。目前对象中的主客队比分属性，在结算中有用到
     */
    @Override
    @Aop(TransAop.REPEATABLE_READ)
    public void goalsNum(JSONArray jsonArray, String mid) {
        log.info("赛果接收,数据:" + jsonArray + ".mid:" + mid);
        // 不更新后台已经手动设置赛果的。如果赛事开赛时间有变化，爬的时候会入库两条，mid相同。所以用query而不是fetch
        List<CrownMatch> matchList = this.query(Cnd.where("mid", "=", mid)
                .and("stage", "!=", CrownConstant.OTHER)
                .and("stage", "!=", CrownConstant.FINISHED));
        // mid加减一
        if (matchList.isEmpty()) {
            int sub = Integer.parseInt(mid) - 1;
            int add = Integer.parseInt(mid) + 1;
            String home = jsonArray.getString(4);
            String custom = jsonArray.getString(5);
            matchList = this.query(Cnd.where("mid", "in", "'" + sub + "','" + add + "'")
                    .and("home", "=", home).and("custom", "=", custom));
            if (matchList.isEmpty()) {
                log.error("赛事mid有误:" + mid + ",接收数据" + jsonArray);
                Date date = DateUtil.parseDate(jsonArray.getString(1) + " " + jsonArray.getString(2) + "m", DateUtil.DATE_FORMAT_PATTERN.Y_M_D_H_M_A.PATTERN);
                if (null == date) {
                    log.info("赛果时间格式错误,mid" + mid + ",时间:" +jsonArray.getString(1) + " " + jsonArray.getString(2));
//                    sysParamService.sendEmail("3412995626@qq.com", "赛果时间格式错误",
//                            "mid：" + mid + ",时间:" +jsonArray.getString(1) + " " + jsonArray.getString(2));
                } else {
                    this.notify(date.getTime() / 1000, mid);
                }
                return;
            }
        }
        String hInBall, cInBall, exInfo;
        // 赛事异常flag
        boolean matchExFlag = false;
        for (CrownMatch match : matchList) {
            for (Map.Entry<Integer, String> entry : tagMap.entrySet()) {
                Integer key = entry.getKey();
                exInfo = jsonArray.getString(key);
                hInBall = jsonArray.getString(key - 2);
                cInBall = jsonArray.getString(key - 1);
                String stage = entry.getValue();
                // 如果异常信息不为空，说明赛事出现异常，取异常信息赋值给比分
                if ((Strings.isNotBlank(exInfo))) {
                    hInBall = exInfo;
                    cInBall = exInfo;
                    // 赛事腰斩不算赛事异常
                    if (CrownConstant.CUT.equals(exInfo)) {
                        match.setIsCut(true);
                    } else {
                        matchExFlag = true;
                    }
                }
                // 校验赛果，如果比分出现‘-’或者空 则 return
                if ("-".equals(hInBall) || "-".equals(cInBall) || Strings.isBlank(hInBall) || Strings.isBlank(cInBall)) {
                    return;
                }
                // 正常赋值赛果
                if ("NO4".equals(stage)) {
                    match.setHInBallHalf(hInBall);
                    match.setCInBallHalf(cInBall);
                } else if ("NO8".equals(stage)) {
                    match.setStage(matchExFlag ? CrownConstant.OTHER : CrownConstant.FINISHED);
                    match.setHInBallFull(hInBall);
                    match.setCInBallFull(cInBall);
                }
                // 更新赛果
                match.setOpAt(Times.getTS());
                matchService.update(match);
            }
        }
    }

    /**
     * 给管理员发送邮件
     *
     * @param time  开赛时间(秒级)
     * @param mid   赛事mid
     */
    private void notify(long time, String mid) {
        // 开赛时间(美东)转系统时间
        long matchTime = DateUtil.timeZoneConvertSys("America/New_York", time);
        long l = System.currentTimeMillis() / 1000 - matchTime;
        // 超过赛事时间2小时 4小时 6小时发送邮件
        if ((l >= 3600 * 2 && l <= 3600 * 2.5) || (l >= 3600 * 4 && l <= 3600 * 4.5) || (l >= 3600 * 6 && l <= 3600 * 6.5)) {
            log.info("赛果获取不到。mid：" + mid + "。开赛时间已过：" + l + "s" + "。位置：re");
//            sysParamService.sendEmail("3412995626@qq.com", "赛果获取不到",
//                    "mid：" + mid + "。开赛时间已过：" + l + "s" + "。位置：re");
        }
    }
}
